package com.zhenyi.liuxue.mini;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.cjw.model.DBMap;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;
import com.liuxue.common.model.LxCertificate;
import com.liuxue.common.model.LxCertificateItem;
import com.liuxue.common.model.LxCertificateItemQuestion;
import com.liuxue.common.model.LxUser;
import com.liuxue.common.model.LxUserCertificate;
import com.liuxue.common.model.LxUserCertificateItem;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;

public class QuestionController extends MiniController {

	/**
	 * 证书列表
	 */
	@Override
	public void list() {
		LxUser user = getUser();
		Kv kv = Kv.create();
		if (user != null) {
			kv.set("userId", user.getId());
		}
		SqlPara sqlPara = Db.use("liuxue").getSqlPara("LXFindCertificates", kv);
		Page<LxCertificate> pages = LxCertificate.dao.paginate(getPage(), PAGE_SIZE, sqlPara);
		renderResult(pages);
	}

	/**
	 * 证书详情
	 */
	@Override
	public void info() {
		Long certificateId = getParaToLong("certificateId");
		LxUser user = getUser();
		if (user == null) {
			renderFailure(401, "Please log in");
			return;
		}
		LxCertificate certificate = LxCertificate.dao.findById(certificateId);
		Kv kv = Kv.create();
		kv.set("certificateId", certificateId);
		kv.set("userId", user.getId());
		SqlPara sqlPara = Db.use("liuxue").getSqlPara("LXFindCourses", kv);
		List<LxCertificateItem> list = LxCertificateItem.dao.find(sqlPara);

		DBMap map = new DBMap();
		map.put("status", 200);
		map.put("msg", "ok");
		map.put("info", certificate);
		map.put("list", list);
		renderJson(map);
	}

	/**
	 * 学习
	 */
	public void study() {
		Long certificateItemId = getParaToLong("certificateItemId");
		if (certificateItemId == null) {
			renderFailure(500, "id is null");
			return;
		}
		LxCertificateItem info = LxCertificateItem.dao.findById(certificateItemId);
		if (info == null || info.getStatus() == -1) {
			renderFailure(404, "not found. invailid id.");
			return;
		}
		if (StrKit.isBlank(info.getContent())) {
			renderFailure(500, "empty content");
			return;
		}
		if (info.getIsVideo().equals(1)) {
			DBMap map = new DBMap();
			map.put("isVideo", 1);
			map.put("url", info.getContent());
			renderResult(map);
		} else {
			String[] list = info.getContent().split(";");
			DBMap map = new DBMap();
			map.put("isVideo", 0);
			map.put("list", list);
			renderResult(map);
		}
		
		// update last study time
		LxUser user = getUser();
		Long certId = info.getCertificateId();
		LxUserCertificate userCert = LxUserCertificate.dao.findById(certId, user.getId());
		if (userCert == null) {
			userCert = new LxUserCertificate();
			userCert.setUserId(user.getId());
			userCert.setCertificateId(certId);
			userCert.setAddTime();
			userCert.setPuid(0L);
			userCert.setStatus(0);
			userCert.save();
		}
		userCert.setLastStudyTime(new Date());
		userCert.update();
	}

	/**
	 * 测试
	 */
	public void exam() {
		Long certificateItemId = getParaToLong("certificateItemId");
		if (certificateItemId == null) {
			renderFailure(500, "course id is null");
			return;
		}
		Kv kv = Kv.create();
		kv.set("certificateItemId", certificateItemId);
		SqlPara sqlPara = Db.use("liuxue").getSqlPara("LXFindCertificateItemQuestion", kv);
		List<LxCertificateItemQuestion> list = LxCertificateItemQuestion.dao.find(sqlPara);
		for (LxCertificateItemQuestion question : list) {
			JSONArray array = JSONUtil.parseArray(question.getAnswers());
			for (int i = 0; i < array.size(); i++) {
				array.getJSONObject(i).put("no", String.valueOf((char) ('A' + i)));
			}
			question.set("answers", array);
		}
		
		// update last exam time
		LxUser user = getUser();
		LxCertificateItem course = LxCertificateItem.dao.findById(certificateItemId);
		Long certId = course.getCertificateId();
		LxUserCertificate userCert = LxUserCertificate.dao.findById(certId, user.getId());
		if (userCert == null) {
			userCert = new LxUserCertificate();
			userCert.setUserId(user.getId());
			userCert.setCertificateId(certId);
			userCert.setAddTime();
			userCert.setPuid(0L);
			userCert.setStatus(0);
			userCert.save();
		}
		userCert.setLastExamTime(new Date());
		userCert.update();
		
		renderResult(list);
	}

	/**
	 * 答题提交
	 */
	public void submitExam() {
		Long certificateItemId = getParaToLong("certificateItemId");
		String answersJson = getPara("answersJson");
		LxUser user = getUser();
		if (user == null) {
			renderFailure(401, "Please log in");
			return;
		}

		LxCertificateItem course = LxCertificateItem.dao.findById(certificateItemId);
		if (course == null) {
			renderFailure(404, "课程不存在");
			return;
		}

		Kv kv2 = Kv.create();
		kv2.set("certificateItemId", certificateItemId);
		SqlPara sqlPara2 = Db.use("liuxue").getSqlPara("LXFindCertificateItemQuestion", kv2);
		List<LxCertificateItemQuestion> list = LxCertificateItemQuestion.dao.find(sqlPara2);
		JSONArray answers = JSONUtil.parseArray(answersJson);

		int correctCount = 0;
		ArrayList<Integer> wrongList = new ArrayList<>();

		for (int i = 0; i < list.size(); i++) {
			LxCertificateItemQuestion question = list.get(i);
			JSONArray array = JSONUtil.parseArray(question.getAnswers());
			if (question.getType().equals(1)) { // 单选
				if (StrKit.notBlank(answers.getStr(i))
						&& array.getJSONObject(answers.getInt(i)).getInt("isAnswer").equals(1)) {
					correctCount++;
				} else {
					wrongList.add(i);
				}
			} else { // 多选
				JSONArray answer = answers.getJSONArray(i);
				boolean allFit = true;
				for (int j = 0; j < array.size(); j++) {
					if (array.getJSONObject(j).getInt("isAnswer").equals(0) && answer.size() > j
							&& answer.getInt(j) != null && answer.getInt(j).equals(1)) {
						allFit = false;
						break;
					}
					if (array.getJSONObject(j).getInt("isAnswer").equals(1)
							&& (answer.size() <= j || answer.getInt(j) == null || answer.getInt(j).equals(0))) {
						allFit = false;
						break;
					}
				}
				if (allFit) {
					correctCount++;
				} else {
					wrongList.add(i);
				}
			}
		}

		// 通过考试
		if (correctCount == list.size()) {
			LxUserCertificateItem userCertificateItem = new LxUserCertificateItem();
			userCertificateItem.setCertificateItemId(certificateItemId);
			userCertificateItem.setUserId(user.getId());
			userCertificateItem.save();
		}

		// 检查是否通过该证书全部考试
		Kv kv = Kv.create();
		kv.set("certificateId", course.getCertificateId());
		kv.set("userId", user.getId());
		SqlPara sqlPara = Db.use("liuxue").getSqlPara("LXFindCourses", kv);
		List<LxCertificateItem> courses = LxCertificateItem.dao.find(sqlPara);
		int passCount = 0;
		for (LxCertificateItem item : courses) {
			if (item.get("userId") != null) {
				passCount++;
			}
		}
		if (passCount == courses.size()) {
			// update pass time
			LxUserCertificate userCert = LxUserCertificate.dao.findById(course.getCertificateId(), user.getId());
			if (userCert == null) {
				userCert = new LxUserCertificate();
				userCert.setUserId(user.getId());
				userCert.setCertificateId(course.getCertificateId());
				userCert.setAddTime();
				userCert.setPuid(0L);
				userCert.setStatus(0);
				userCert.save();
			}
			userCert.setPassTime(new Date());
			userCert.setStatus(1);
			userCert.update();
			
			// 获得证书 +100 积分
			user.setPoint(user.getPoint() + 100);
			user.update();
		}

		DBMap map = new DBMap();
		map.put("total", list.size());
		map.put("correctCount", correctCount);
		map.put("isPass", correctCount == list.size() ? 1 : 0);
		map.put("isAllPass", passCount == courses.size() ? 1 : 0);
		map.put("coursesLeft", courses.size() - passCount);
		if (correctCount != list.size()) {
			map.put("wrongList", wrongList);
		}
		if (passCount == courses.size()) {
			map.put("certificateId", course.getCertificateId());
		}
		renderResult(map);
	}
	
	public void certificateInfo() {
		Long certificateId = getParaToLong("certificateId");
		if (certificateId == null) {
			renderFailure(500, "id is null");
			return;
		}
		LxCertificate cert = LxCertificate.dao.findById(certificateId);
		if (cert == null) {
			renderFailure(404, "not found");
			return;
		}
		renderSuccess(cert);
	}
}
